/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.palomino.servicios;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.util.Hashtable;

/**
 *
 * @author JONATHAN
 */
public class TLOracle_General {

    static final int PUERTO = 1;
    static final int SERVIDOR = 0;
    public final static String DRIVERORACLE = "oracle.jdbc.OracleDriver";
    public final static String URLCONEXION = "jdbc:oracle:thin:@";
    public static final int INICIAR = 0;
    public static final int SEGUIR = 1;
    public static final int CERRAR = 2;
    static Hashtable htConexiones = new Hashtable();
    static Hashtable htDatosUsuario = new Hashtable();
    static Hashtable htbCodigo = new Hashtable();
    static String sVacio = "";
    static boolean bTrazaActiva = false;
    static UsuariosSAPTronBD usuariosSAPT = null;
    // Sentencias para listas de valores.
    static String sSentenciaFetch = "? := trn_k_lv.f_devuelve_fila(?)";
    static String sSentenciaPQuery = "begin trn_k_lv.p_query(2); end;";
    static String sSenActUsuario = "begin trn_k_ap101108.p_inserta_modifica(17); end;";
    static final String sSentenciaGetPropiedades = "{ ? = call trn_k_ap101107.traer_propiedades(?)}";
    static String sSenGlobalesCabeceras = "begin ? := trn_k_lv.f_devuelve_nombre_globales; ? := trn_k_lv.f_devuelve_cabecera_con_tipo; end;";
    static String sSenCampos = "begin ? := trn_k_lv.f_devuelve_cabecera_t; end;";
    static String sSenFiltroOrden = "begin trn_k_lv.p_devuelve_fila_filtro_orden(7); end;";
    static String sSenFiltraOrdena = "begin trn_k_lv.p_query_con_filtro_orden(1); end;";
    static final String sentenciaGetUsuario = "begin trn_k_ap101108.p_recupera_datos_usuario(17); end;";
    static String[] asModosDU = {"IN OUT", "OUT", "OUT", "OUT", "OUT", "OUT", "OUT", "OUT", "OUT", "OUT", "OUT", "OUT", "OUT", "OUT", "OUT", "OUT", "OUT"};
    static String[] asModosUsuario = {"IN OUT", "OUT"};
    static String[] asFormatosFiltroOrden = {"OUT", "OUT", "OUT", "OUT", "OUT", "OUT", "OUT"};
    static String[] asFormatosPQuery = {"IN", "IN"};
    static String[] asFmtFiltraOrdena = {"IN"};
    static String[] asFmtGlobalesCabeceras = {"OUT", "OUT"};
    static String[] asFormatosFetch = {"OUT", "IN"};
    static String sSenAsignaGlobal = "begin trn_k_global.asigna (?,?); end;";
    static String[] asFmtAsignaGlobal = {"IN", "IN"};
    static String sSentenciaServidores = "{ ? = call ss_k_tronweb_servidores.tr_recupera_servidores(?)}";
    static String[] asFmtAServidores = {"IN OUT", "OUT", "OUT", "OUT"};
    static String sSenListaGlobales = "begin ? := trn_k_global.lista; end;";
    static String[] aFmtListaGlobales = {"OUT"};

    static public Object[] ejecutaSentenciaMRS(String psSesion, boolean pbDesdePackage, String pSentencia, String[] pFormatos, Object[] pInOut, String[] pTipos, boolean pInicializa, boolean pbPreparar) throws java.rmi.RemoteException {
        SAPDatosUsuarioHTTP miUsuario = (SAPDatosUsuarioHTTP) htbCodigo.get("" + psSesion);
        if (miUsuario == null) {
            String res = "SAP 346 TRN-00000 No hay Conexi¢n";
            //Traza.error(res, psSesion);
            return null;
        }
        return ejecutaSentencia(psSesion, miUsuario.getConexionORA(), pbDesdePackage, pSentencia, pFormatos, pInOut, pTipos, pInicializa, pbPreparar);
    }

    static public Object[] ejecutaSentencia(String psSesion, Connection pConexion, boolean pbDesdePackage, String pSentencia, String[] pFormatos, Object[] pInOut, String[] pTipos, boolean pInicializa, boolean pbPreparar) throws java.rmi.RemoteException {
        Object[] lDatosInOut = null;
        if (pInOut != null) {
            lDatosInOut = (Object[]) pInOut.clone();
        }
        CallableStatement vlSentencia = null;

        if (pbPreparar) {
            pSentencia = preparaSentencia(pSentencia, isVersion9());
        }

        if (pConexion != null) {
            try {
                if (pInicializa == true) {
                    vlSentencia = pConexion.prepareCall(pSentencia);
                    if (pFormatos != null && pInOut != null) {
                        int xIn = 1;
                        if (isVersion9()) {
                            vlSentencia.registerOutParameter(xIn, java.sql.Types.VARCHAR);
                            vlSentencia.setString(xIn, psSesion);
                            xIn = 2;
                        }
                        for (int x = 0; x < pFormatos.length; x++) {
                            if (pTipos != null && !TLOracle_General.nvl(pTipos[x]).equals("")) {
                                vlSentencia.registerOutParameter(x + xIn, java.sql.Types.DATE);
                            } else {
                                vlSentencia.registerOutParameter(x + xIn, java.sql.Types.VARCHAR);
                            }

                            if (pFormatos[x].indexOf("IN") > (-1)) {
                                if (pTipos != null && !TLOracle_General.nvl(pTipos[x]).equals("")) {
                                    if (pInOut != null && !((String) pInOut[x]).trim().equals("")) {
                                        Fecha fechaSql = new Fecha((String) pInOut[x], pTipos[x]);
                                        vlSentencia.setDate(x + xIn, fechaSql.getFechaSQL());
                                    } else {
                                        vlSentencia.setNull(x + xIn, java.sql.Types.DATE);
                                    }
                                } else {
                                    if (pInOut[x] != null && !((String) pInOut[x]).trim().equals("")) {
                                        vlSentencia.setString(x + xIn, ((String) pInOut[x]).trim());
                                    } else {
                                        vlSentencia.setNull(x + xIn, java.sql.Types.VARCHAR);
                                    }
                                }
                            } else if (pTipos == null || TLOracle_General.nvl(pTipos[x]).equals("")) {
                                vlSentencia.setString(x + xIn, sVacio);
                            }
                        }
                    }
                }
                vlSentencia.execute();


                if (pFormatos != null && pInOut != null) {
                    for (int x = 0; x < pFormatos.length; x++) {
                        if (pFormatos[x].indexOf("OUT") > (-1)) {
                            if (pTipos != null && !TLOracle_General.nvl(pTipos[x]).equals("")) {
                                if (vlSentencia.getDate(x + 1) != null) {
                                    Fecha fechaSQL = new Fecha();
                                    fechaSQL.setFechaSQL(vlSentencia.getString(x + 1), pTipos[x]);
                                    pInOut[x] = fechaSQL.getFecha();
                                } else {
                                    pInOut[x] = null;
                                }
                            } else {
                                pInOut[x] = vlSentencia.getString(x + 1);
                            }
                        }
                    }
                }
                vlSentencia.close();
            } catch (java.sql.SQLException sqle) {
                //Traza.stack(sqle, psSesion);
                try {
                    vlSentencia.close();
                } catch (java.sql.SQLException e2) {
                    //Traza.error("Error Cerrando el cursor", psSesion);
                    pInOut = null;
                }
                pInOut = null;
                String textoError = TLOracle_General.analizaErrorSql(sqle);
                //Traza.error(textoError + "\n\tSEN: " + setDatosSentencia(pSentencia, pFormatos, lDatosInOut), psSesion);
                throw new java.rmi.RemoteException(textoError, sqle);
            } catch (Exception e) {
                String res = "TRN-00000 Error No Oracle al ejecutar Sentencia: " + e.getMessage();
                //Traza.error(res, psSesion);
                pInOut = null;
                throw new java.rmi.RemoteException(res, e);
            }
        }
        return pInOut;
    }

    static String preparaSentencia(String pSentencia, boolean pbOra9) {
        StringBuffer lbSentencia = new StringBuffer(TLOracle_General.sacaInterrogaciones(pSentencia));
        if (lbSentencia.toString().startsWith("BEGIN")
                || lbSentencia.toString().startsWith("begin")
                || lbSentencia.toString().startsWith("DECLARE")
                || lbSentencia.toString().startsWith("declare")); else {
            lbSentencia.insert(0, "BEGIN ");
            lbSentencia.append("; END;");
        }
        if (pbOra9) {
            lbSentencia.insert(0, "BEGIN BEGIN trn_k_contexto.p_setsesion(?); END; ");
            lbSentencia.append(" END;");
        }
        return lbSentencia.toString();
    }

    public static String sacaInterrogaciones(String psOrigen) {

        if (psOrigen.indexOf("(?") > (-1)) // Tiene Interrogaciones, por lo que no convierte.
        {
            return psOrigen.trim();
        }

        int desde = psOrigen.indexOf("(");
        if (desde == (-1)) // No tiene parámetros, por lo que no convierte.
        {
            return psOrigen.trim();
        }
        int hasta = psOrigen.indexOf(")");
        if (hasta == (-1)) // No tiene parámetros, por lo que no convierte.
        {
            return psOrigen.trim();
        }

        String lsDato = psOrigen.substring(desde + 1, hasta);

        int cuanto = 0;
        try {
            cuanto = new Integer(lsDato).intValue();
        } catch (java.lang.NumberFormatException e) {
        }

        String resultado = psOrigen.substring(0, desde + 1);
        for (int x = 0; x < cuanto; x++) {
            if (x > 0) {
                resultado += ",";
            }
            resultado += "?";
        }
        resultado += psOrigen.substring(hasta);
        return resultado.trim();
    }

    /**
     * analizaErrorSql Recupera la parte de Texto de una Exception de SQL
     */
    static public String analizaErrorSql(java.sql.SQLException e) {
        return analizaErrorSql(e.getMessage(), e.getErrorCode());
    }

    static public String analizaErrorSql(String psMensaje, int piCodigo) {
        String res = "";
        int k = -1;
        int j = -1;
        if (psMensaje.indexOf("ORA-06550") > (-1)) {
            k = psMensaje.lastIndexOf("PLS-");
            j = psMensaje.lastIndexOf(10, k);
        } else if (psMensaje.lastIndexOf("TRN-") > (-1)) {
            k = psMensaje.lastIndexOf("TRN-");
            j = psMensaje.indexOf(10, k);
        } else if (psMensaje.indexOf("ORA-") > (-1)) {
            k = psMensaje.indexOf("ORA-");
            j = psMensaje.indexOf(10, k);
        } else if (psMensaje.lastIndexOf(10) > (-1)) {
            k = 0;
            j = psMensaje.lastIndexOf(10);
        }
        if (k > j) {
            return psMensaje.substring(k).replace((char) 10, (char) 32);
        }
        if (k == -1) {
            return psMensaje.replace((char) 10, (char) 32);
        }
        if (j == -1) {
            return psMensaje.substring(k).replace((char) 10, (char) 32);
        }
        return psMensaje.substring(k, j).replace((char) 10, (char) 32);
    }

    /**
     * Quita espacios de un String. <br>Si la cadena es
     * <code>null</code> devuelve la cadena vacía "" <br>Si la cadena pasada a
     * minúsculas es <i>"null"</i> devuelve la cadena vacía "" <br>En caso
     * contrario quita los espacios del principio y del final de la cadena
     *
     * @param psOrigen cadena que se desea limpiar de espacios
     * @return cadena sin espacios iniciales y finales
     */
    static public String nvl(String psOrigen) {
        if (psOrigen == null) {
            return new String("");
        }
        if (psOrigen.trim().toLowerCase().equals("null")) {
            return new String("");
        }
        return psOrigen.trim();
    }

    private static boolean isVersion9() {
        return false;
    }
}
